package util.file;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import util.BaseUtil;

import java.io.*;

/**
 * @AUTHOR : yangfan
 * @DATE : 2016/11/29
 * @TIME : 14:55
 * @VERSION : 1.0
 * @DESC : 文件操作类
 */
public class FileUtil extends BaseUtil {

	private final static Logger LOGGER = LoggerFactory.getLogger(FileUtil.class);

	private FileUtil() {
		LOGGER.debug("FileUtil");
		throw new AssertionError(getClass().getName() + " has no default instances.");
	}

	/**
	 * 创建相关文件夹
	 *
	 * @param file
	 */
	public static boolean makeDir(File file) {

		if (!file.exists()) {
			if (file.mkdirs()) {
				LOGGER.debug(FileConstant.MAKE_DIR_SUCCESS);
				return FileConstant.OPERATION_SUCCESS;
			}
			LOGGER.debug(FileConstant.MAKE_DIR_FAILED);
			return FileConstant.OPERATION_FAILED;
		}
		LOGGER.debug(FileConstant.PATH_IS_EXIST);
		return FileConstant.OPERATION_FAILED;
	}

	/**
	 * 删除文件夹以及其下的文件
	 *
	 * @param file
	 * @return 所有文件删除true, otherwise:false;
	 */
	public static boolean deleteDir(File file) {
		if (file.exists() && file.isDirectory()) {
			File[] files = file.listFiles();
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory()) {
					deleteDir(files[i]);
				}
				deleteFile(files[i]);
			}
			if (file.delete()) {
				LOGGER.debug(file + FileConstant.DELETE_SUCCESS);
				return FileConstant.OPERATION_SUCCESS;
			} else {
				System.err.println(file + FileConstant.DELETE_FAILED);
				return FileConstant.OPERATION_FAILED;
			}
		} else {
			return FileConstant.OPERATION_FAILED;
		}
	}

	/**
	 * 重命名文件夹
	 *
	 * @param file
	 * @param newName
	 * @return 重新命名文件夹
	 */
	public static boolean renameDir(File file, String newName) {
		File newFile = new File(file.getParent() + File.separator + newName);
		return file.renameTo(newFile);
	}

	/**
	 * 创建文件
	 *
	 * @param file
	 * @return boolean 创建文件成功与否
	 */
	public static boolean createFile(File file) {
		try {
			return file.createNewFile();
		} catch (IOException e) {
			LOGGER.error(FileConstant.PATH_IS_USELESS_AND_CREATE);
			if (makeDir(file.getParentFile())) {
				return createFile(file);
			} else {
				LOGGER.error(FileConstant.MAKE_DIR_FAILED);
				return FileConstant.OPERATION_FAILED;
			}
		}
	}

	/**
	 * 写入文件内容(指定编码)
	 *
	 * @param file
	 * @param content
	 */
	public static boolean writeFile(File file, String content, String encodeType) {
		try {
			FileOutputStream fileOutputStream = new FileOutputStream(file);
			OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, encodeType);
			LOGGER.debug("写入文件内容...");
			BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
			bufferedWriter.write(content);
			bufferedWriter.close();
			outputStreamWriter.close();
			fileOutputStream.close();
			LOGGER.debug("写入结束.");
			return FileConstant.OPERATION_SUCCESS;
		} catch (UnsupportedEncodingException e) {
			LOGGER.error(FileConstant.UNSUPPORTED_ENCODE_USE_DEFAULT_ENCODE);
			return writeFile(file, content, FileConstant.DEFAULT_ENCODE_TYPE);
		} catch (FileNotFoundException e) {
			LOGGER.error(FileConstant.PATH_IS_USELESS_AND_CREATE);
			if (makeDir(file.getParentFile())) {
				if (createFile(file)) {
					return writeFile(file, content, encodeType);
				}
			}
			return FileConstant.OPERATION_FAILED;
		} catch (IOException e) {
			LOGGER.error(FileConstant.IO_EXCEPTION);
			return FileConstant.OPERATION_FAILED;
		}
	}

	/**
	 * 写入文件（未指定编码）
	 *
	 * @param file
	 * @param content
	 * @return
	 */
	public static boolean writeFile(File file, String content) {
		LOGGER.debug(FileConstant.USE_DEFAULT_ENCODE);
		return writeFile(file, content, FileConstant.DEFAULT_ENCODE_TYPE);
	}

	/**
	 * 删除文件
	 *
	 * @param file
	 */
	public static boolean deleteFile(File file) {
		if (file.exists()) {
			if (file.delete()) {
				LOGGER.debug(FileConstant.DELETE_SUCCESS);
				return FileConstant.OPERATION_SUCCESS;
			} else {
				LOGGER.debug(FileConstant.DELETE_FAILED);
				return FileConstant.OPERATION_FAILED;
			}
		} else {
			LOGGER.error("文件不存在!");
			return false;
		}
	}

	/**
	 * 编辑文件(可更改编码)
	 *
	 * @param file
	 * @param content
	 * @param encodeType
	 */
	public static boolean editFile(File file, String content, String encodeType) {
		return writeFile(file, content, encodeType);
	}

	/**
	 * 编辑文件(默认编码)
	 *
	 * @param file
	 * @param content
	 * @return boolean
	 */
	public static boolean editFile(File file, String content) {
		return writeFile(file, content, FileConstant.DEFAULT_ENCODE_TYPE);
	}

	/**
	 * 向文件追加内容(指定编码)
	 *
	 * @param file
	 * @param appendStr
	 * @param encodeType
	 * @return 追加成功与否
	 */
	public static boolean appendFile(File file, String appendStr, String encodeType) {
		try {
			//构建随机读写,设置mode读写
			RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
			//获取文件长度
			long length = randomAccessFile.length();
			//指针移到最后
			randomAccessFile.seek(length);
			//文件内容追加,设置编码格式
			randomAccessFile.write(appendStr.getBytes(encodeType));
			randomAccessFile.close();
			LOGGER.debug(FileConstant.APPEND_SUCCESS);
			return FileConstant.OPERATION_SUCCESS;
		} catch (FileNotFoundException e) {
			LOGGER.error(FileConstant.PATH_IS_USELESS_AND_CREATE);
			return false;
		} catch (UnsupportedEncodingException e) {
			LOGGER.error(FileConstant.UNSUPPORTED_ENCODE_USE_DEFAULT_ENCODE);
			return appendFile(file, appendStr);
		} catch (IOException e) {
			return FileConstant.OPERATION_FAILED;
		}
	}

	/**
	 * 向文件追加内容(未指定编码)
	 *
	 * @param file
	 * @param appendStr
	 * @return 追加成功与否
	 */
	public static boolean appendFile(File file, String appendStr) {
		LOGGER.debug(FileConstant.USE_DEFAULT_ENCODE);
		return appendFile(file, appendStr, FileConstant.DEFAULT_ENCODE_TYPE);
	}

	/**
	 * 读取文件（指定编码格式）
	 *
	 * @param file
	 * @param encodeType
	 * @return 读取的文件内容
	 */
	public static String readFile(File file, String encodeType) {
		String content = "";
		try {
			FileInputStream fileInputStream = new FileInputStream(file);
			InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, encodeType);
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			content = bufferedReader.readLine();
			bufferedReader.close();
			inputStreamReader.close();
			fileInputStream.close();
		} catch (UnsupportedEncodingException e) {
			LOGGER.error(FileConstant.UNSUPPORTED_ENCODE_USE_DEFAULT_ENCODE);
			return readFile(file, FileConstant.DEFAULT_ENCODE_TYPE);
		} catch (FileNotFoundException e) {
			LOGGER.error(FileConstant.FILE_IS_NOT_EXITS);
		} catch (IOException e) {
			LOGGER.error(FileConstant.IO_EXCEPTION);
		}
		return content;
	}

	/**
	 * 读取文件(未指定编码)
	 *
	 * @param file
	 * @return 读取的文件内容
	 */
	public static String readFile(File file) {
		LOGGER.debug(FileConstant.USE_DEFAULT_ENCODE);
		return readFile(file, FileConstant.DEFAULT_ENCODE_TYPE);
	}
}
